package com.dongdongshop.service.impl;

import cn.hutool.json.JSONUtil;
import com.dongdongshop.api.GoodsServiceApi;
import com.dongdongshop.constant.CacheConstant;
import com.dongdongshop.data.Result;
import com.dongdongshop.domain.vo.CartDetailVO;
import com.dongdongshop.domain.vo.CartVO;
import com.dongdongshop.dto.ItemDTO;
import com.dongdongshop.service.CartService;
import com.dongdongshop.util.JwtUtil;
import com.dongdongshop.util.UserVO;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private GoodsServiceApi goodsServiceApi;

    @Override
    public void addCart(Long skuId, Integer number, String autharizeToken) {
        //获取到用户的username
        Claims claims = JwtUtil.parseJwt(autharizeToken);
        String subject = claims.getSubject();//用户对象
        UserVO userVO = JSONUtil.toBean(subject, UserVO.class);//转成uservo类型的数据
        String username = userVO.getName();
        //获取购物车的数据
        List<CartVO> cartListByRedis = getCartListByRedis(username);
        //根据商品id去查询商品信息
        Result<ItemDTO> result = goodsServiceApi.getItemById(skuId);
        ItemDTO item = result.getData();
        //获取商家id
        if (result.getCode() != 0){//如果操作失败
            throw new RuntimeException("查询失败");//抛出一个运行时异常
        }
        String sellerId = item.getSellerId();//商家id

        //1。判断当前用户是否加购过当前商家的商品
        CartVO cart = getCartVOBySellerId(sellerId, cartListByRedis);
        //如果没加购过 cart == null
        if (cart == null){
            cart = new CartVO();
            cart.setSellerId(item.getSellerId());//商家id
            //创建购物车明细数据
            CartDetailVO cartDetailVO = new CartDetailVO();
            cartDetailVO.setItemId(item.getId());//商品sku的id
            cartDetailVO.setNum(number);//加入购物车的数量
            cartDetailVO.setImage(item.getImage());//图片
            cartDetailVO.setPrice(item.getPrice());//单价
            cartDetailVO.setTitle(item.getTitle());//标题
            cartDetailVO.setSellerId(item.getSellerId());//商家的id
            cartDetailVO.setTotalMoney(new BigDecimal(number * item.getPrice().doubleValue()));//总价
            //创建CartDetailVO集合
            List<CartDetailVO> cartDetailVOList = new ArrayList<>();
            cartDetailVOList.add(cartDetailVO);
            //明细集合放到商家购物车cart中
            cart.setCartDetailVOList(cartDetailVOList);
            //商家购物车放到用户的购物车中
            cartListByRedis.add(cart);
        } else {//如果加购过这个商家的商品, cart != null
            List<CartDetailVO> cartDetailVOList = cart.getCartDetailVOList();
            //判断我们是否买过该商品
            CartDetailVO detailVO = getCartDetailVOByItemId(cartDetailVOList, item.getId());
            if (detailVO == null){//如果我们没有加购过该商家的此类商品
                //加购
                detailVO = new CartDetailVO();
                detailVO.setItemId(item.getId());//商品sku的id
                detailVO.setNum(number);//加入购物车的数量
                detailVO.setImage(item.getImage());//图片
                detailVO.setPrice(item.getPrice());//单价
                detailVO.setTitle(item.getTitle());//标题
                detailVO.setSellerId(item.getSellerId());//商家的id
                detailVO.setTotalMoney(new BigDecimal(number * item.getPrice().doubleValue()));//总价
                //追加到原来的明细列表中
                cartDetailVOList.add(detailVO);
            } else {//当我们加购过该商家的同一类商品
                //修改小计即可(购买的数量)
                detailVO.setNum(detailVO.getNum() + number);//修改数量
                detailVO.setTotalMoney(new BigDecimal(detailVO.getNum() * detailVO.getPrice().doubleValue()));//修改总价
                if (detailVO.getNum() <= 0){//如果购买的数量为0了, 那么移出对应的明细数据
                    cartDetailVOList.remove(detailVO);
                }
                if (cartDetailVOList.isEmpty()){//如果商家的购物车没有内容了, 那么移出该商家的购物车
                    cartListByRedis.remove(cart);
                }
            }
        }

        //存入redis中
        addCartRedis(username,cartListByRedis);
    }

    //从缓存中获取购物车的数据
    public List<CartVO> getCartListByRedis(String username) {
        //从redis中获取数据
        List<CartVO> cartVOList = (List<CartVO>) redisTemplate.boundValueOps(CacheConstant.CART_CACHE_PREFIX + username).get();
        if (cartVOList == null) {//第一次加入购物车
            cartVOList = new ArrayList<>();
        }
        return cartVOList;
    }

    //封装一个方法, 在集合中根据商家id获取到该用户购物车中同一个商家的商品, 用于判断购物车中是否有该商家的商品
    public CartVO getCartVOBySellerId(String sellerId, List<CartVO> cartVOList){
        return cartVOList.stream().filter(cartVO -> Objects.equals(sellerId,cartVO.getSellerId())).findFirst().orElse(null);
    }

    //封装一个方法, 在集合中根据商品id获取到用户在该商家所加购的商品是否已经加购过
    public CartDetailVO getCartDetailVOByItemId(List<CartDetailVO> cartDetailVOList, Long itemId){
        return cartDetailVOList.stream().filter(detailVO -> Objects.equals(detailVO.getItemId(),itemId)).findFirst().orElse(null);
    }

    //存入redis
    public void addCartRedis(String username,List<CartVO> cartList){
        redisTemplate.boundValueOps(CacheConstant.CART_CACHE_PREFIX+username).set(cartList);
    }

    //查询购物车
    @Override
    public List<CartVO> selectCart(String autharizeToken) {
        //获取到用户的username
        Claims claims = JwtUtil.parseJwt(autharizeToken);
        String subject = claims.getSubject();//用户对象
        UserVO userVO = JSONUtil.toBean(subject, UserVO.class);//转成uservo类型的数据
        String username = userVO.getName();
        return getCartListByRedis(username);
    }

    @Override
    public void delCart(String autharizeToken) {
        //获取到用户的username
        Claims claims = JwtUtil.parseJwt(autharizeToken);
        String subject = claims.getSubject();//用户对象
        UserVO userVO = JSONUtil.toBean(subject, UserVO.class);//转成uservo类型的数据
        String username = userVO.getName();
        redisTemplate.delete(CacheConstant.CART_CACHE_PREFIX+username);
    }
}
